package bintree.leetcode;

/**
 * @Author: yuisama
 * @Date: 2022/10/8 15:10
 * @Description:不同的BST
 */
public class Num96_NumBSTrees {
    // 备忘录解决递归中重复计算的子树个数
    int[][] memo;
    public int numTrees(int n) {
        memo = new int[n + 1][n + 1];
        return count(1,n);
    }
    /**
     * 在区间[lo..hi]上可以构造出多少不同的BST
     * @param lo
     * @param hi
     * @return
     */
    private int count(int lo, int hi) {
        // base case
        // 空区间对应空树，空树本身也是一种BST，此处返回1
        if (lo > hi) return 1;
        // 查备忘录
        if (memo[lo][hi] != 0) {
            return memo[lo][hi];
        }
        int res = 0;
        for (int i = lo; i <= hi; i++) {
            // 左子树为当前元素左区间
            int left = count(lo,i - 1);
            // 右子树为当前元素右区间
            int right = count(i + 1,hi);
            // 左右子树之积就是当前以i为根的BST的个数
            res += left * right;
        }
        // 存备忘录
        memo[lo][hi] = res;
        return res;
    }
}
